﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Windows.Interop;
using System.Runtime.InteropServices; 

/// <summary>
/// This code was taken from 
/// 
/// http://www.swart.ws/2009/03/kiosk-full-screen-wpf-applications.html 
/// 
/// Thursday July 9/2009
/// </summary>
namespace AMPLibrary.Windows
{
    public static class FullScreenHelper
    {
        public static double GoFullscreen(Window window)
        {
            if (window == null)
                return 0.0;

            // Make window borderless  
            window.WindowStyle = WindowStyle.None;
            window.ResizeMode = ResizeMode.NoResize;

            // Get handle for nearest monitor to this window  
            WindowInteropHelper wih = new WindowInteropHelper(window);
            if (wih == null)
                return 0.0;

            IntPtr hMonitor = MonitorFromWindow(wih.Handle, MONITOR_DEFAULTTONEAREST);
            if (hMonitor == null)
                return 0.0;

            // Get monitor info  
            MONITORINFOEX monitorInfo = new MONITORINFOEX();
            if (monitorInfo == null)
                return 0.0;

            monitorInfo.cbSize = Marshal.SizeOf(monitorInfo);
            GetMonitorInfo(new HandleRef(window, hMonitor), monitorInfo);

            // Create working area dimensions, converted to DPI-independent values  
            HwndSource source = HwndSource.FromHwnd(wih.Handle);
            if (source == null)
                return 0.0; // Should never be null  

            if (source.CompositionTarget == null)
                return 0.0; // Should never be null  

            Matrix matrix = source.CompositionTarget.TransformFromDevice;
            RECT workingArea = monitorInfo.rcMonitor;
            Point dpiIndependentSize = matrix.Transform(new Point(workingArea.Right - workingArea.Left, workingArea.Bottom - workingArea.Top));

            // Maximize the window to the device-independent working area ie  
            // the area without the taskbar.  
            // NOTE - window state must be set to Maximized as this adds certain  
            // maximized behaviors eg you can't move a window while it is maximized,  
            // such as by calling Window.DragMove  
            window.MaxWidth = dpiIndependentSize.X;
            window.MaxHeight = dpiIndependentSize.Y;
            window.WindowState = WindowState.Maximized;

            return window.MaxWidth;
        }

        // Nearest monitor to window  
        const int MONITOR_DEFAULTTONEAREST = 2;

        // To get a handle to the specified monitor  
        [DllImport("user32.dll")]
        static extern IntPtr MonitorFromWindow(IntPtr hwnd, int dwFlags);

        // To get the working area of the specified monitor  
        [DllImport("user32.dll")]
        public static extern bool GetMonitorInfo(HandleRef hmonitor, [In, Out] MONITORINFOEX monitorInfo);

        // Rectangle (used by MONITORINFOEX)  
        [StructLayout(LayoutKind.Sequential)]
        public struct RECT
        {
            public int Left;
            public int Top;
            public int Right;
            public int Bottom;
        }

        // Monitor information (used by GetMonitorInfo())  
        [StructLayout(LayoutKind.Sequential)]
        public class MONITORINFOEX
        {
            public int cbSize;
            public RECT rcMonitor; // Total area  
            public RECT rcWork; // Working area  
            public int dwFlags;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 0x20)]
            public char[] szDevice;
        }
    }
}